package com.ovopark.firecar.okhttp;

import static com.alibaba.fastjson.JSON.parseObject;

import android.text.TextUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.caoustc.okhttplib.Constants;
import com.caoustc.okhttplib.okhttp.BaseHttpRequestCallback;
import com.caoustc.okhttplib.okhttp.OkHttpManager;
import com.caoustc.okhttplib.okhttp.OkHttpRequestParams;
import com.caoustc.okhttplib.okhttp.Part;
import com.caoustc.okhttplib.okhttp.model.BaseDataObject;
import com.caoustc.okhttplib.okhttp.model.BaseDataObject2;
import com.caoustc.okhttplib.okhttp.platform.Stat;
import com.caoustc.okhttplib.okhttp.utils.ParseUtils;
import com.caoustc.okhttplib.utils.StringUtils;
import com.socks.library.KLog;


import java.util.HashMap;
import java.util.List;

import okhttp3.Headers;


/**
 * 网络框架转化类，
 * 从okhttp转换到retrofit+okhttp。
 *
 * @author caixingming 2020/11/12.
 */
public class OkHttpToRetrofit implements HttpRequestLoader {

    private static final String TAG = "OkHttpToRetrofit";

    private static volatile OkHttpToRetrofit mOkHttpLib = null;
    /**
     * 默认解析参数
     */
    private String parseKey = "data";
    private String parseKeyTwo = "data";

    private OkHttpToRetrofit() {
    }

    public static OkHttpToRetrofit getInstance() {
        synchronized (OkHttpToRetrofit.class) {
            if (mOkHttpLib == null) {
                mOkHttpLib = new OkHttpToRetrofit();
            }
        }
        //f初始化parsekey防止被重置.
        mOkHttpLib.setParseKeyTwo("data", "data");

        return mOkHttpLib;
    }

    /**
     * 设置解析的双层data数据key关键字，默认data:{data:{}}
     *
     * @param parseKey_
     * @param parseKeyTwo_
     * @return
     */
    public OkHttpToRetrofit setParseKeyTwo(String parseKey_, String parseKeyTwo_) {
        if (!TextUtils.isEmpty(parseKey_)) {
            this.parseKey = parseKey_;
        }
        if (!TextUtils.isEmpty(parseKeyTwo_)) {
            this.parseKeyTwo = parseKeyTwo_;
        }
        return this;
    }

    @Override
    public void postFormParseRequest(String url, OkHttpRequestParams params, BaseHttpRequestCallback callback) {
        postFormParseRequest(url, params, null, callback);
    }

    @Override
    public void postFormParseRequest(String url, OkHttpRequestParams params, int timeout, BaseHttpRequestCallback callback) {
        postFormParseRequest(true, url, params, timeout, null, callback);
    }

    @Override
    public void postFormParseRequest(boolean isCancel, String url, OkHttpRequestParams params, BaseHttpRequestCallback callback) {
        postFormParseRequest(isCancel, url, params, null, callback);
    }

    @Override
    public void postFormParseRequest(boolean isCancel, String url, OkHttpRequestParams params, int timeout, BaseHttpRequestCallback callback) {
        postFormParseRequest(isCancel, url, params, timeout, null, callback);
    }

    @Override
    public void postFormParseRequest(String url, OkHttpRequestParams params, Class dataClass, BaseHttpRequestCallback callback) {
        postFormParseRequest(true, url, params, dataClass, callback);
    }

    @Override
    public void postFormParseRequest(String url, OkHttpRequestParams params, int timeout, Class dataClass, BaseHttpRequestCallback callback) {
        postFormParseRequest(true, url, params, timeout, dataClass, callback);
    }


    @Override
    public void postFormParseRequest(boolean isCancel, String url, OkHttpRequestParams params, Class dataClass, BaseHttpRequestCallback callback) {
        postFormParseRequest(isCancel, url, params, Constants.REQ_TIMEOUT, dataClass, callback);
    }

    @Override
    public void postFormParseRequest(boolean isCancel, String url, OkHttpRequestParams params, int timeout, Class dataClass, final BaseHttpRequestCallback callback) {
//        KLog.i("okhttp","postFormParseRequest~");
        //直接的网络请求结构体.
        RequestSender requestSender = RequestSender.getInstance();
//        KLog.i(TAG, "postFormParseRequest() start ~~~~~~~~~~~~~~~~~~~~~~~"+url);
        //转换parmas.
        //show progress .
        if (null != callback) {
            callback.onStart();
        }

        HashMap rfHeaders = new HashMap();
        HashMap rfParams = new HashMap();

        if (params != null) {
            //headers.
            Headers headerParams = params.headers.build();
            if (null != headerParams && headerParams.size() > 0) {
                for (int i = 0; i < headerParams.size(); i++) {
                    rfHeaders.put(headerParams.name(i), headerParams.value(i));
                }
            }
            //params。
            List<Part> bodyParams = params.getFormParams();
            if (null != bodyParams && bodyParams.size() > 0) {
                for (int i = 0; i < bodyParams.size(); i++) {
                    rfParams.put(bodyParams.get(i).getKey(), bodyParams.get(i).getValue());
                }
            }

            // DO: 2020/12/22 判断是否是文件上传，如果是则走文件上传的api.
            if (params.isFileUpload()) {
                requestSender.upLoadRequestRaw(new RequestSender.RequestData(url, rfParams, rfHeaders,
                        response -> {//返回成功.
                            KLog.i(TAG, "postFormParseRequest() success ~~~~~~~~~~~~~~~~~~~~~~~" + url);
                            handleResponse(response, dataClass, callback);
                        },
                        error -> {//位置错误.
                            KLog.i(TAG, "postFormParseRequest() failed ~~~~~~~~~~~~~~~~~~~~~~~");
                            handlerError(error, callback);
                        }), params.getRequestBody());
                return;
            }
            //DO: 2020/12/11 json格式的请求需要额外处理. 复杂数据处理. '
            if (params.isApplicationJson()) {
                requestSender.sendRequestRaw(new RequestSender.RequestData(url, rfParams, rfHeaders,
                        response -> {//返回成功.
                            KLog.i(TAG, "postFormParseRequest() success ~~~~~~~~~~~~~~~~~~~~~~~" + url);
                            handleResponse(response, dataClass, callback);
                        },
                        error -> {//位置错误.
                            KLog.i(TAG, "postFormParseRequest() failed ~~~~~~~~~~~~~~~~~~~~~~~");
                            handlerError(error, callback);
                        }), params.getRequestBody());
                return;
            }
        }


        //结果转换器.数据转换器.
        requestSender.sendRequest(new RequestSender.RequestData(url, rfParams, rfHeaders,
                response -> {//返回成功.
//                    KLog.i(TAG, "postFormParseRequest() success ~~~~~~~~~~~~~~~~~~~~~~~"+url);
                    handleResponse(response, dataClass, callback);
                },
                error -> {//位置错误.
                    KLog.i(TAG, "postFormParseRequest() failed ~~~~~~~~~~~~~~~~~~~~~~~");
                    handlerError(error, callback);
                }));
    }

    @Override
    public void putFormParseRequest(String url, OkHttpRequestParams params, Class dataClass, BaseHttpRequestCallback callback) {
        KLog.i(TAG, "okhttp", "getFormParseRequest~");
        //直接的网络请求结构体.
        RequestSender requestSender = RequestSender.getInstance();
        //show progress .
        if (null != callback) {
            callback.onStart();
        }

        //转换parmas.
//        this.dataClass = dataClass;
        HashMap rfHeaders = new HashMap();
        HashMap rfParams = new HashMap();

        //headers.
        if (params != null) {
            Headers headerParams = params.headers.build();
            if (null != headerParams && headerParams.size() > 0) {
                for (int i = 0; i < headerParams.size(); i++) {
                    rfHeaders.put(headerParams.name(i), headerParams.value(i));
                }
            }

            //params。
            List<Part> bodyParams = params.getFormParams();
            if (null != bodyParams && bodyParams.size() > 0) {
                for (int i = 0; i < bodyParams.size(); i++) {
                    rfParams.put(bodyParams.get(i).getKey(), bodyParams.get(i).getValue());
                }
            }
        }

        KLog.i(TAG, "getFormParseRequest() start ~~~~~~~~~~~~~~~~~~~~~~~");

        //结果转换器.数据转换器.
        requestSender.sendPutRequest(new RequestSender.RequestData(url, rfParams, rfHeaders,
                response -> {//返回成功.
                    KLog.i(TAG, "getFormParseRequest() success ~~~~~~~~~~~~~~~~~~~~~~~" + url);
                    handleResponse(response, dataClass, callback);
                },
                error -> {//位置错误.
                    KLog.i(TAG, "getFormParseRequest() failed ~~~~~~~~~~~~~~~~~~~~~~~");
                    handlerError(error, callback);
                }));
    }

    @Override
    public void getFormParseRequest(String url, OkHttpRequestParams params, Class dataClass, BaseHttpRequestCallback callback) {
        KLog.i(TAG, "okhttp", "getFormParseRequest~"+url);
        //直接的网络请求结构体.
        RequestSender requestSender = RequestSender.getInstance();
        //show progress .
        if (null != callback) {
            callback.onStart();
        }

        //转换parmas.
//        this.dataClass = dataClass;
        HashMap rfHeaders = new HashMap();
        HashMap rfParams = new HashMap();

        //headers.
        if (params != null) {
            Headers headerParams = params.headers.build();
            if (null != headerParams && headerParams.size() > 0) {
                for (int i = 0; i < headerParams.size(); i++) {
                    rfHeaders.put(headerParams.name(i), headerParams.value(i));
                    KLog.i(TAG,"head "+i+":"+headerParams.name(i)+":"+headerParams.value(i));
                }
            }

            //params。
            List<Part> bodyParams = params.getFormParams();
            if (null != bodyParams && bodyParams.size() > 0) {
                for (int i = 0; i < bodyParams.size(); i++) {
                    rfParams.put(bodyParams.get(i).getKey(), bodyParams.get(i).getValue());
                }
            }
        }

        KLog.i(TAG, "getFormParseRequest() start ~~~~~~~~~~~~~~~~~~~~~~~");

        //结果转换器.数据转换器.
        requestSender.sendGetRequest(new RequestSender.RequestData(url, rfParams, rfHeaders,
                response -> {//返回成功.
                    KLog.i(TAG, "getFormParseRequest() success ~~~~~~~~~~~~~~~~~~~~~~~" + url);
                    handleResponse(response, dataClass, callback);
                },
                error -> {//位置错误.
                    KLog.i(TAG, "getFormParseRequest() failed ~~~~~~~~~~~~~~~~~~~~~~~");
                    handlerError(error, callback);
                }));
    }

    public void postFormParseJSONArray(String url, OkHttpRequestParams params, Class dataClass, BaseHttpRequestCallback callback) {
        KLog.i("okhttp", "postFormParseJSONArray~");
        //直接的网络请求结构体.
        RequestSender requestSender = RequestSender.getInstance();
        KLog.i(TAG, "postFormParseJSONArray() start ~~~~~~~~~~~~~~~~~~~~~~~");
        //show progress .
        if (null != callback) {
            callback.onStart();
        }
        //转换parmas.
        HashMap rfHeaders = new HashMap();
        HashMap rfParams = new HashMap();

        if (params != null) {
            //headers.
            Headers headerParams = params.headers.build();
            if (null != headerParams && headerParams.size() > 0) {
                for (int i = 0; i < headerParams.size(); i++) {
                    rfHeaders.put(headerParams.name(i), headerParams.value(i));
                }
            }
            //params。
            List<Part> bodyParams = params.getFormParams();
            if (null != bodyParams && bodyParams.size() > 0) {
                for (int i = 0; i < bodyParams.size(); i++) {
                    rfParams.put(bodyParams.get(i).getKey(), bodyParams.get(i).getValue());
                }
            }
        }

        //结果转换器.数据转换器.
        requestSender.sendPostArrayRequest(new RequestSender.RequestData(url, rfParams, rfHeaders,
                response -> {//返回成功.
                    KLog.i(TAG, "postFormParseJSONArray() success ~~~~~~~~~~~~~~~~~~~~~~~" + url);
                    handleResponse(response, dataClass, callback);
                },
                error -> {//位置错误.
                    KLog.i(TAG, "postFormParseJSONArray() failed ~~~~~~~~~~~~~~~~~~~~~~~");
                    handlerError(error, callback);
                }));
    }

    @Override
    public void getFormParseRequest(String url, OkHttpRequestParams params, BaseHttpRequestCallback callback) {
        getFormParseRequest(url, params, null, callback);
    }


    /**
     * 处理复杂数据类型 ，1-2曾data数据结构
     * {data:{
     * data:{xxxxxxxxxxxxxxx}
     * }
     * result:"ok"
     * }
     *
     * @param response
     * @param callback
     */
    private void handleResponse(Object response, Class dataClass, BaseHttpRequestCallback callback) {
//        KLog.i(TAG, "handleResponse()");
        //回调为空，不向下执行
        if (callback == null) {
            return;
        }

        String result = response.toString();

        if (StringUtils.isEmpty(result)) {
            callback.onFailure(Constants.ERROR_RESPONSE_NULL, "服务异常");
        }
//        KLog.json(TAG, result);


        if (callback.baseRequestType == String.class) {//字符串类型.
            //callback.onSuccess(responseData.getHeaders(), result);
            callback.onSuccess(result);
            return;
        } else if (callback.baseRequestType == JSONObject.class) {//JsonObject .
            JSONObject jsonObject = null;
            try {
                jsonObject = parseObject(result);
            } catch (Exception e) {
                KLog.e("okhttp", e.getMessage());
            }
            if (jsonObject != null) {
                callback.onSuccess(jsonObject);
                return;
            }
        } else if (callback.baseRequestType == JSONArray.class) {//JsonArray .
            JSONArray jsonArray = null;
            try {
                jsonArray = JSON.parseArray(result);
            } catch (Exception e) {
                KLog.e("okhttp", e.getMessage());
            }

            if (jsonArray != null) {
                callback.onSuccess(jsonArray);
                return;
            }

        } else if (callback.baseDataType == BaseDataObject.class ||
                callback.baseDataType == BaseDataObject2.class) {//解析{data：{data:{}}} 数据集合.
            JSONObject jsonObject = null;
            try {
                jsonObject = parseObject(result);

                if (jsonObject != null) {
                    //get "result" data .
                    String resultCode = ParseUtils.parseResult(jsonObject, "result");
                    String message = ParseUtils.parseResult(jsonObject, "message");
                    String desc = ParseUtils.parseResult(jsonObject, "desc");
                    Boolean isError = ParseUtils.parseBoolean(jsonObject, "isError");
                    Object data = jsonObject.get("data");
                    //如果结果不正确 .中断返回.
                    if (!StringUtils.isResultOk(resultCode, isError, desc)) {

                        //DO: 2021/5/11 解决离线设备问题.
                        JSONObject dataObject = jsonObject.getJSONObject("data");
                        if (null != dataObject) {
                            String errorCode = dataObject.getString("errorCode");
                            if (!TextUtils.isEmpty(errorCode)) {
                                callback.onSuccessError(resultCode, errorCode);
                                return;
                            }
                        }

                        //新接口错误码统一放置到了message.
                        if (TextUtils.isEmpty(resultCode)) {
                            resultCode = message;
                        }

                        if (OkHttpManager.getInstance().getHttpErrorManager() != null) {
                            callback.onSuccessError(resultCode, OkHttpManager.getInstance().getHttpErrorManager().onResultMessage(resultCode));
                        } else {
                            callback.onSuccessError(resultCode, "服务异常");
                        }
                        return;
                    }

                    if (callback.baseDataType == BaseDataObject2.class) {//2层data数据结构解析.
                        if (jsonObject.containsKey(parseKey)) {//去掉一层data.
                            JSONObject dataObject = jsonObject.getJSONObject(parseKey);
                            Integer total = ParseUtils.parseTotal(dataObject, "total");
//                            if(null != dataClass){
//                                KLog.i(TAG,"2层data解析：total:"+total+": "+ "<"+dataClass.getName()+">"+dataObject.toString());
//                            }
                            Object obj = ParseUtils.parseJson(dataObject, parseKeyTwo, callback.baseRequestType, dataClass);
                            callback.onSuccess(obj);
                            callback.onSuccess(obj, total);
                            return;
                        }
                    } else if (callback.baseDataType == BaseDataObject.class) {//1层data数据结构解析.
                        if (data instanceof Integer) {
                            KLog.i(TAG, "on success result: " + data);
                            callback.onSuccess(data);
                            return;
                        }
                        Object obj = ParseUtils.parseJson(jsonObject, parseKey, callback.baseRequestType, dataClass);
                        callback.onSuccess(obj);
                        return;
                    }
                }
            } catch (Exception e) {
                KLog.e("okhttp", e.getMessage());
                e.printStackTrace();
            }
        } else if (callback.baseDataType == Stat.class) {
            JSONObject jsonObject = null;
            try {
                jsonObject = parseObject(result);
                if (jsonObject != null) {
                    Stat mStat = ParseUtils.parseStat(jsonObject);
                    if (!StringUtils.isResultSuccess(mStat)) {
                        callback.onSuccessError(mStat);
                        return;
                    }

                    Integer total = ParseUtils.parseTotal(jsonObject, "total");
                    Object obj = ParseUtils.parseJson(jsonObject, parseKey, callback.baseRequestType, dataClass);
                    callback.onSuccess(obj, mStat);
                    callback.onSuccess(obj, mStat, total);
                    return;
                }
            } catch (Exception e) {
                KLog.e("okhttp", e.getMessage());
                e.printStackTrace();
            }
        } else {//正常data数据结构. {data:{},message:"SUCCESS",code:"0",isError:false}
            Object obj = null;
            try {
                obj = parseObject(result, callback.baseRequestType);
                if (obj != null) {
                    callback.onSuccess(obj);
                    return;
                }
            } catch (Exception e) {
                KLog.e("okhttp", e.getMessage());
                e.printStackTrace();
            }
        }

        callback.onFailure(Constants.ERROR_RESPONSE_DATA_PARSE_EXCEPTION, "服务异常");
    }

    /**
     * 处理错误返回.
     *
     * @param error
     * @param callback
     */
    private void handlerError(Throwable error, BaseHttpRequestCallback callback) {
        if (null == callback) return;
        KLog.i(TAG, "handlerError()");
        if (null != error && error.getMessage() != null) {
            callback.onFailure(RetrofitConstant.ERROR_RESPONSE_UNKNOWN, error.getMessage());
        } else {
            callback.onFailure(RetrofitConstant.ERROR_RESPONSE_UNKNOWN, null);
        }
    }

}